package com.sgst.job.job;

import com.sgst.job.services.entity.*;
import com.sgst.job.services.service.*;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author pywang
 * @Description
 * @date 2020-04-24 13:38
 **/
@Component
@AllArgsConstructor
public class QyDataSync {

    private final IEquipInfoService equipInfoService;
    private final IYqxxService yqxxService;
    private final IYqxxAppAreaService yqxxAppAreaService;
    private final IYqxxSubjectAreaService yqxxSubjectAreaService;
    private final IYqxxCustomsInfoService yqxxCustomsInfoService;
    private final IYqxxOperatorService yqxxOperatorService;
    private final IYqxxSccsService yqxxSccsService;
    private final INstrCategoryService nstrCategoryService;
    private final INstrNationService nstrNationService;
    private final INstrSubjectService nstrSubjectService;

    public void sync(){
        List<String> oldList = yqxxService.getOldList().stream().map(t->t.replace("\t", ""))
                .map(t->t.trim()).collect(Collectors.toList());
        List<Yqxx> yqxxList = equipInfoService
                .listEquipInfo()
//                .lambdaQuery()
//                .notInSql(EquipInfo::getInnerId, "select prop_mng_num from yqxx where prop_mng_num is not null")
//                .list()
                .stream()
                .filter(t->!oldList.contains(t.getInnerId()))
                .map(JsonUtils::objectToMap)
                .map(t -> dataTransform(t, getFieldMapper()))
                .map(t -> JsonUtils.mapToObject(t, Yqxx.class))
                .map(t -> t.setId(UUID.randomUUID().toString())
                            .setRemoved(0).setMergeStatus("LAW_UN_SUBMIT").setNote1("qy"))
                .collect(Collectors.toList());
        yqxxService.saveBatch(yqxxList);
        yqxxList.forEach(t->{
            if (StringUtils.isNotEmpty(t.getField())){
                List<YqxxAppArea> appAreaList = Stream.of(t.getField().split("/"))
                        .map(f -> new YqxxAppArea().setInstrId(t.getId())
                                .setCreateTime(new Date())
                                .setAppArea(f).setId(UUID.randomUUID().toString()))
                        .collect(Collectors.toList());

                yqxxAppAreaService.saveBatch(appAreaList);
            }
            if (StringUtils.isNotEmpty(t.getEquipSubject())){
                List<YqxxSubjectArea> subjectAreas = Stream.of(t.getEquipSubject().split(","))
                        .map(s -> new YqxxSubjectArea().setInstrId(t.getId())
                                .setCreateTime(new Date()).setSubjectArea(s).setId(UUID.randomUUID().toString())
                        ).collect(Collectors.toList());
                yqxxSubjectAreaService.saveBatch(subjectAreas);
            }

            if (StringUtils.isNotEmpty(t.getOp1Name())){
                yqxxOperatorService.save(new YqxxOperator().setInstruId(t.getId())
                    .setAge(t.getOp1Age()).setCreateTime(new Date())
                        .setCreateUser("qy")
                        .setSpecial(t.getOp1Speciality())
                        .setTechLevel(t.getOp1TechLevel())
                        .setGoodAt(t.getOp1Advantege())
                        .setMajor(t.getOp1EduLevel())
                        .setOperateName(t.getOp1Name())
                        .setTechPost(t.getOp1Title())
                        .setOperateId(UUID.randomUUID().toString())
                );
            }

        });
    }

    private Map<String, Object> dataTransform(Map<String, Object> data, List<FieldMapperConfig> fieldMapper) {
        Map<String, Object> rs = new HashMap<>();
        fieldMapper
            .forEach(t->{
                Object d = data.get(t.getFromStr());
                rs.put(t.getTarget(), convertByTransformer(d, t.getTransformer()));
            });
        return rs;
    }

    private Object convertByTransformer(Object obj, String transformer) {
        if (obj == null){
            return null;
        }
        if (StringUtils.isEmpty(transformer)){
            return obj;
        }
        switch (transformer){
            case "insCode":
                return transfromInsCode(obj);
            case "subject":
                return transformSubject(obj);
            case "nation":
                return transformNation(obj);
        }
        return obj;
    }

    private Object transformNation(Object obj) {
        if (StringUtils.isEmpty(String.valueOf(obj))){
            return obj;
        }
        return getNationDic()
                .stream()
                .filter(t-> Objects.equals(t.getNationCode(), String.valueOf(obj)))
                .findFirst()
                .map(NstrNation::getNation)
                .orElse(String.valueOf(obj));
    }

    private Object transformSubject(Object obj) {
        if (StringUtils.isEmpty(String.valueOf(obj))){
            return obj;
        }
        Map<String, String> dic = getSubjectDic();
        return Stream.of(String.valueOf(obj)
                .split(","))
                .map(t->dic.get(t) == null? "无": dic.get(t))
                .collect(Collectors.joining(","))
        ;
    }

    private static List<NstrSubject> subjects = new ArrayList<>();
    private static List<NstrNation> nations = new ArrayList<>();

    private Map<String, String> getSubjectDic() {
        if(CollectionUtils.isEmpty(subjects)){
            subjects = nstrSubjectService.list();
        }
        return subjects.stream().collect(Collectors.toMap(NstrSubject::getSubCode, NstrSubject::getSubName));
    }

    private List<NstrNation> getNationDic() {
        if(CollectionUtils.isEmpty(nations)){
            nations = nstrNationService.list();
        }
        return nations;
    }

    private Object transfromInsCode(Object obj) {
        if (obj == null){
            return null;
        }
        switch (String.valueOf(obj)){
            case "shjt":
                return "10000236";
            case "shtj":
                return "10000246";
            case "shhl":
                return "10000255";
            case "hdsf":
                return "10000223";
        }

        return obj;
    }

    private List<FieldMapperConfig> getFieldMapper() {
        try {
            return FileUtils.readLines(new File("D:\\temp\\mapperConfig.txt"), "UTF-8")
            .stream().map(t->t.split(",")).map(t->new FieldMapperConfig(t.length>=2?t[1]:null,t[0],t.length>=3?t[2]:null))
            .collect(Collectors.toList())
            ;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Collections.emptyList();
    }
}
